<!--
 * @description 列表选择框、表格选择框
 * @author shenguangyang
-->
<template>
  <div
    v-bind="$attrs"
    class="matu-listselect"
  >
    <div>
      <template v-for="(item, _index) in headerButtons" :key="_index">
        <a-button
          size="small"
          class="ml-4"
          v-auth="item.props.buttonAuth"
          @click="item.handleOpenModal(item.props.buttonComp)"
        >
          <Icon icon="i-fluent:add-12-filled" /> {{ t(item.props.buttonText) }}
        </a-button>
        <component
          :is="item.modalComponent"
          v-model:open="item.modalComponentOpen"
          @register="item.registerModal"
          @success="item.handleSuccess(tableAction)"
        />
      </template>
    </div>
    <ARow>
      <ACol :span="4" v-if="props.config.treeProps" :style="getTreeStyle">
        <a-card>
          <BasicTree
            :title="props.config.treeProps.title"
            :search="true"
            :toolbar="true"
            :showIcon="true"
            :api="props.config.treeProps.api"
            :params="props.config.treeProps.params"
            :defaultExpandLevel="2"
            @select="handleTreeSelect"
          />
        </a-card>
        
      </ACol>
      <ACol :span="props.config.treeProps ? 17 : 18" class="overflow-hidden">
        <a-card>
          <BasicTable
            @register="registerTable"
            :canResize="true"
            :minHeight="tableHeight"
            :maxHeight="tableHeight"
            class="matu-listselect-table"
          />
        </a-card>
      </ACol>
      <ACol :span="props.config.treeProps ? 3 : 6" >
        <a-card class="select-data-card pl-2 pt-1">
          {{ t(`已选择${selectTitleSuffix}`, [selectList.length]) }}：
          <div
            class="matu-listselect-tags mt-2"
            v-if="selectList && selectList.length > 0"
            :style="`height:${treeHeight}px`"
          >
            <Tag
              v-for="(item, index) in selectList"
              :key="getObjValue(item, props.config.itemCode)"
              color="processing"
            >
              <Tooltip :title="getTagTip(item)" placement="bottom">
                <span class="tag-text" >
                  {{ getObjValue(item, props.config?.itemName) }}
                  {{
                    props.config?.isShowCode !== false ? ' (' + getObjValue(item, props.config.itemCode) + ')' : ''
                  }}
                </span>
              </Tooltip>
              <Icon icon="i-ant-design:close-outlined" @click="closeTag(index)" />
            </Tag>
          </div>
        </a-card>
      </ACol>
    </ARow>
  </div>
</template>
<script lang="ts" setup>
  import { defineComponent, ref, toRaw, CSSProperties, computed, watch, shallowRef, onMounted } from 'vue';
  import { Row, Col, Tag, Tooltip } from 'ant-design-vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { BasicTree } from '/@/components/Tree';
  import { Icon } from '/@/components/Icon';
  import { BasicTable, useTable, BasicTableProps, TableRowSelection } from '/@/components/Table';
  import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
  import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
  import { dynamicImport } from '/@/router/helper/routeHelper';
  import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
  import { useModal } from '/@/components/Modal';
  import { getObjValue } from '/@/utils';
  const ARow = Row;
  const ACol = Col;

  const { t } = useI18n();

  const props = defineProps({
    maxHeight: { type: Number as PropType<Number>, required: false },
    config: { type: Object as PropType<any> },
    selectTitleSuffix: { type: String as PropType<String> },
    selectList: { type: Object as PropType<any> },
    queryParams: { type: Object as PropType<any>, required: false},
    checkbox: { type: Boolean },
  });

  const emit = defineEmits(['select', 'register']);

  const treeHeight = ref<Number>(400);
  const tableHeight = ref<Number>(400);
  const getTagTip = (item) => {
    return item[props.config.itemName] + (item[props.config.itemDesc] ? `（${item[props.config.itemDesc]}）` : '')
  }

  const getTreeStyle = computed((): CSSProperties => {
    return {
      height: `${treeHeight.value}px`,
      minHeight: `${treeHeight.value}px`,
    };
  });
  function calcTreeHeight() {
    let height = document.documentElement.clientHeight;
    treeHeight.value = height - 280;
    tableHeight.value = height - 380;

    treeHeight.value = props.maxHeight && treeHeight.value > props.maxHeight ? props.maxHeight : treeHeight.value
    tableHeight.value = props.maxHeight && tableHeight.value > props.maxHeight ? props.maxHeight : tableHeight.value
  }
  useWindowSizeFn(calcTreeHeight, 280);
  onMountedOrActivated(calcTreeHeight);

  const selectList = ref<Recordable[]>([]);

  type Key = string | number;
  const selectedRowKeys = ref<Key[]>([]);
  const initialize = ref<boolean>(false);

  
  const rowSelection: TableRowSelection = {
    type: props.checkbox ? 'checkbox' : 'radio',
    columnWidth: props.checkbox ? 25 : 0,
    selectedRowKeys: selectedRowKeys as unknown as Key[],
    onChange: (_selectedRowKeys: Key[], selectedRows: Recordable[]) => {

      console.log('selectedRows', tableAction.getSelectRowKeys())
      if (!initialize.value) return; // 首次加载不更新状态，会将初始值清空
      selectedRowKeys.value = tableAction.getSelectRowKeys();
      selectList.value = selectedRowKeys.value.map(e => {
        return {
          rowKey: e,
          ...JSON.parse(e), 
        }
      })
      if (props.checkbox) {
        emit('select', selectList.value);
      } else if (selectList.value.length > 0) {
        emit('select', [selectList.value[0]]);
      } else {
        emit('select', []);
      }
    },
    onSelect: (record,  selected: boolean, selectedRows: Object[], _) => {
      if (!props.checkbox && selected) {
        emit('select', [record]);
      } else {
        emit('select', []);
      }
    }
  };

  const tableProps: BasicTableProps = {
    showTableSetting: false,
    useSearchForm: true,
    canResize: true,
    resizeHeightOffset: 100,
    rowSelection,
    clearSelectedOnReload: false,
    ...props.config?.tableProps,
    beforeFetch: (params) => {
      params = { ...params, ...props.queryParams }
      return params;
    },
    rowKey: 'rowKey',
    afterFetch: (list) => {
      list?.forEach(data => {
        const rowKeys = {}
        props.config.tableRowKeys.forEach((key) => {
          rowKeys[key] = data[key]
        })
        data.rowKey = JSON.stringify(rowKeys)
      })
      initialize.value = true;
    },
  };

  const [registerTable, tableAction] = useTable(tableProps);
  const headerButtons = ref<any[]>([]);

  const init = async () => {
    if (!props.selectList) {
      return
    }

    // 拼接多个字段作为rowKey目的是解决跨页选中问题
    selectList.value = props.selectList.map(e => {
      const rowKeys = {}
      props.config.tableRowKeys.forEach((key) => {
        rowKeys[key] = e[key]
      })
      e.rowKey = JSON.stringify(rowKeys)
      return e;
    });


    selectedRowKeys.value = selectList.value.map((e) => e.rowKey);

    if (props.queryParams) {
      const params = Object.assign(tableAction.getForm().getFieldsValue(), props.queryParams);
      await tableAction.getForm().setFieldsValue(params);
    }
    if (props.config.headerButtons) {
      headerButtons.value = [];
      for (const item of props.config.headerButtons) {
        const [registerModal, inputAction] = useModal();
        const modalComponent = shallowRef<Nullable<any>>(null);
        const modalComponentOpen = ref<Boolean>(false);
        headerButtons.value.push({
          props: item,
          registerModal,
          modalComponent,
          modalComponentOpen,
          handleOpenModal: (buttonComp) => {
            let component: ReturnType<typeof defineComponent>;
            const imp = dynamicImport(buttonComp);
            if (imp) component = createAsyncComponent(imp);
            if (component) {
              modalComponent.value = component;
              inputAction.setModalData({});
              modalComponentOpen.value = true;
            }
          },
          handleSuccess: (tableAction: any) => {
            tableAction.reload();
          },
        });
      }
    }
  }
  onMounted(async () => {
    init()
  })

  watch(
    () => props.selectList,
    () => {
      init()
    },
    { deep: true },
  );


  // const rowClick = (record: Recordable) => {
  //   if (!props.checkbox) {
  //     selectList.value = [record];
  //   }
  // };

  const closeTag = (index: number) => {
    const keys = tableAction.getSelectRowKeys() as string[];
    const newKeys = keys.filter(e => e != selectList.value[index]['rowKey'])
    tableAction.setSelectedRowKeys(newKeys);
    selectList.value.splice(index, 1);
  };

  async function handleTreeSelect(keys: string[]) {
    const values = {};
    values[props.config.treeTableFieldName] = keys[0];
    await tableAction.getForm().setFieldsValue(values);
    await tableAction.reload();
  }
</script>
<style lang="less">

  .matu-listselect {
    .ant-card .ant-card-body {
      padding: 3px !important;
    }

    .select-data-card {
      margin-left: 5px !important;
      height: 100%;
    }
  }
  .matu-listselect-table {

    .ant-table-wrapper {
      .ant-table {
        td {
          cursor: pointer;
        }
      }
    }

    &.matu-basic-table-form-container {
      .ant-form.matu-basic-form {
        border-top: 0 !important;
      }
    }
  }

  .matu-listselect {
    .ant-modal.matu-basic-modal {
      .ant-modal {
        &-body {
          > .scrollbar {
            .scrollbar__wrap {
              margin-top: 0;
              margin-bottom: 0;
            }
          }
        }
      }
    }

    .matu-basic-tree-header {
      padding: 15px 0 4px;
      border: 0;
    }

    &-tags {
      overflow: auto;

      .ant-tag {
        margin: 4px 0 0;
        padding: 0 4px;
        width: 100%;
        display: flex;
        justify-content: space-between;

        span {
          overflow: hidden;
          white-space: nowrap;
          cursor: default;
        }

        .tag-text {
          width: 100%;
        }

        .anticon {
          margin-left: 4px !important;
          height: 20px;
          cursor: pointer;
        }
      }
    }
  }
</style>
